package com.yifeng.repo.base.utils.file;

import com.talkyun.utils.download.FastLoader;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * Created by daibing on 2019/10/27.
 */
public class FileHelper {

    public static String getFileName(String fileName) {
        int lastPeriodIndex = fileName.lastIndexOf("/");
        if (lastPeriodIndex > 0 && lastPeriodIndex + 1 < fileName.length()) {
            return fileName.substring(lastPeriodIndex + 1).toLowerCase();
        }
        return null;
    }

    public static String getSuffix(String fileName) {
        int lastPeriodIndex = fileName.lastIndexOf(".");
        if (lastPeriodIndex > 0 && lastPeriodIndex + 1 < fileName.length()) {
            return fileName.substring(lastPeriodIndex + 1).toLowerCase();
        }
        return null;
    }

    public static String getCurrentDir() {
        File file = new File(FileHelper.class.getProtectionDomain().getCodeSource().getLocation().getFile());
        try {
            return URLDecoder.decode(file.getParent(), StandardCharsets.UTF_8.name());
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    public static void removeFile(Collection<String> files) {
        for (String file : files) {
            removeFolder(new File(file));
        }
    }

    public static boolean removeFolder(File path) {
        if (path.isFile()) {
            return path.delete();
        }
        File[] subFiles = path.listFiles();
        if (subFiles != null) {
            for (File subFile : subFiles) {
                removeFolder(subFile);
            }
        }
        return path.delete();
    }

    public static List<File> listSubFile(File path, boolean onlyFile) {
        File[] fileArray = path.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return !(name.startsWith(".") || name.endsWith(".iml") || name.endsWith("target"));
            }
        });
        if (fileArray == null) {
            return Collections.emptyList();
        }
        List<File> files = new ArrayList<>();
        for (File file : fileArray) {
            if (onlyFile) {
                if (file.isFile()) {
                    files.add(file);
                }
            } else {
                files.add(file);
            }
            if (file.isDirectory()) {
                files.addAll(listSubFile(file, onlyFile));
            }
        }
        return files;
    }

    public static void copy(File sourcePath, File targetPath) throws IOException {
        copy(sourcePath, targetPath, true);
    }

    public static void copy(File sourcePath, File targetPath, boolean onlyFile) throws IOException {
        if (!sourcePath.exists()) {
            return;
        }
        copy(sourcePath, targetPath, listSubFile(sourcePath, onlyFile));
    }

    public static void copyByPath(File sourcePath, File targetPath, Collection<String> copyFilePaths) throws IOException {
        List<File> copyFiles = new ArrayList<>(copyFilePaths.size());
        for (String copyFilePath : copyFilePaths) {
            copyFiles.add(new File(copyFilePath.startsWith(sourcePath.getPath()) ? copyFilePath : sourcePath.getPath() + copyFilePath));
        }
        copy(sourcePath, targetPath, copyFiles);
    }

    public static void copy(File sourcePath, File targetPath, Collection<File> copyFiles) throws IOException {
        for (File source : copyFiles) {
            File target = new File(source.getPath().replace(sourcePath.getPath(), targetPath.getPath()));
            if (!source.exists()) {
                continue;
            }
            if (!target.getParentFile().exists()) {
                target.getParentFile().mkdirs();
            }
            Files.copy(source.toPath(), target.toPath(), StandardCopyOption.REPLACE_EXISTING);
        }
    }

    public static File createDir(String path) {
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
        return file;
    }

    public static File createFile(String path) {
        File file = new File(path);
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return file;
    }

    public static String newFilePath(String cloneFilePath, String addFileName) {
        int pos = cloneFilePath.lastIndexOf(".");
        return cloneFilePath.substring(0, pos) + addFileName + cloneFilePath.substring(pos);
    }

    public static void downloadFile(String url, File localFile, int downTaskNum) throws IOException {
        if (!localFile.getParentFile().exists()) {
            localFile.getParentFile().mkdirs();
        }
        new FastLoader(url, localFile.getPath(), downTaskNum).load();
    }

    public static void copyFile(File sourceFile, File targetFile) throws IOException {
        if (!targetFile.getParentFile().exists()) {
            targetFile.getParentFile().mkdirs();
        }
        Files.copy(sourceFile.toPath(), targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
    }

    public static void main(String[] args) throws Exception {
        File file = new File("C:\\Users\\Administrator\\Desktop\\poi-exam\\mytest\\demo (x-1).xlsx");
        System.out.println(file.getPath());
        System.out.println(file.getAbsolutePath());
        System.out.println(file.toPath());
        System.out.println(file.getParent());
        System.out.println(file.getParentFile());

//        File target = new File("C:\\Users\\Administrator\\Desktop\\poi-exam\\mytest\\demo (x-1).xlsx");
//        Files.copy(file.toPath(), target.toPath(), StandardCopyOption.REPLACE_EXISTING);
//        System.out.println(target.getPath());

//        List<String> dirs = extract(Arrays.asList("/Users/daibing/Downloads/32jre/rt.create"));
//        System.out.println("dirs: " + dirs);

//        List<String> jars = create(Arrays.asList("D:\\temp\\clean\\lib\\rt"));
//        System.out.println("jars: " + jars);

    }
}
